this and closureswindow and document, that represent a client-side web application and all HTML elements
are visible in JS code.
window and document, be used?var p = 10; ... var p = 15; alert(p);window object as a property.obj.property_name or obj['property_name']obj.method_name(...) or obj['method_name'](...)let property_name = ...; let property_value = ...; obj[property_name] = property_value;let method_name = ...; let method_code = ...; obj[method_name] = method_code; obj[method_name](...);
// These are both globals.
let foo = 1; // If 'var' is used instead, this variable will be created in the 'window' object as a property.
// If the property exists, it will be overwritten. Need to be careful.
let bar = 2;
function test_scope() {
let foo = 1; // Local
bar = 3; // Global
// Execute an anonymous function. Isn't it interesting?
(function() {
let wibble = 1; // Local
foo = 2; // Inherits from the scope above (creating a closure)
moo = 3; // Global
})();
}
test_scope();
window
data[anyindex] = ...;
person[2] = 'Dave';.
What do you see?
Array.isArray(data)
for...in and for...of
delete person.age;
let x = {};
Object.defineProperty(x, "p", { value : 3, writable: true, enumerable: false, configurable: true});
Object.defineProperty(x, "p", { writable: false} );
alert(Object.getOwnPropertyDescriptor(x, "p").writable); // .getOwnPropertyDescriptor() returns {vale:..., writable:..., enumerable:..., configurable:...}.
function Apple (type) { // This is similar to the definition of a class in Java.
// The keyword is function, not class.
// A function is a constructor that is instantiated later.
this.type = type; // this.type: global; type: local
this.color = "red";
this.getInfo = function() {
return this.color + ' ' + this.type + ' apple';
};
};
let apple = new Apple('macintosh'); // keyword 'new' to create an object
apple.color = "reddish";
alert(apple.getInfo());
//-----------------------------------------------------------
function Car (type, color) {
this.type = type;
this.color = color;
};
let passat = new Car('passenger', 'black');
Car.prototype.size = 'small';
Car.prototype.getInfo = function() { // Car.prototype
return this.color + ' ' + this.type + ' car';
};
let golf = new Car('passenger', 'silver');
alert(golf.getInfo());
alert(passat.getInfo()); // ???
let apple = new function() {
this.type = "macintosh";
this.getInfo = function () {
return this.color + ' ' + this.type + ' apple';
};
}
apple.color = "reddish";
alert(apple.getInfo());
let o = {}; // or var o = new Object();
// for arrays
let a = []; // or var a = new Array();
//-----------------------------------------------------------
let apple = { // In this case you cannot create another instance of the class later.
type: "macintosh",
color: "red",
getInfo: function () {
return this.color + ' ' + this.type + ' apple';
}
}
apple.color = "reddish";
alert(apple.getInfo());
//-----------------------------------------------------------
{
let apple = {};
apple.type = 'Gala'; // Not apple.prototype.type. Why?
apple.color = 'Red';
apple.getInfo = function () {
return this.color + ' ' + this.type + ' apple';
};
alert(apple.getInfo());
}
$trujs and $trujs._expressions with its value.
The property name is given with a user-defined attribute 'trujs-model'.
function fruit(type) {
if (type == "GoldenDelicious")
return {
type: "GoldenDelicious",
color: "yellow",
getInfo: function () {
return this.color + ' ' + this.type + ' apple';
}
}
else if (type == "PinkLady")
return {
type: "PinkLady",
color: "pink",
getInfo: function () {
return this.color + ' ' + this.type + ' apple';
}
}
else
return {
type: "Unknown";
}
}
let apple = fruit("GoldenDelicious");
alert(apple.getInfo);
$trujq function that has a paramter of CSS selector and returns an object.
The returned object needs to have the method click() that responses to the click event on the HTML elements that are selected with the passed CSS selector.
const person = (function(n, a) { // What value does person have? function() { ... or the returned function?
// What is (function() { ... })()? Function invocation?
let name = n;
let age = a;
return { // What kind of data is returned?
first_name: name,
get_name: function() { return name; }, // NOT this.name
set_name: function(new_name) { name = new_name; },
get_age: function() { return age; }, // NOT this.age
set_age: function(new_age) { age = new_age; }
};
})('Tim', 22);
alert(person.age); // undefined; why???
alert(person.first_name); // 'Tim'
person.first_name = 'Gildong'; // This first_name is the public variable.
alert(person.first_name); // 'Gildong'; It does not change the private variable, name.
alert(person.get_name()); // 'Tim'
alert(person.get_age());
person.set_age(24);
alert(person.get_age());
Student function using the above Module pattern.
The object returned from Student needs to keep private name and id.
The object has setName(), getName(), setId(), and getId() methods to access them.
$trujq function that has a parameter of CSS selector and returns an object.
The returned object needs to have the method click() that responses to the click event on the selected HTML elements with the passed CSS selector.
Note that the click() method has a parameter of function which will be invoked in a click event listener.
$trujq function that has a parameter of CSS selector and returns an object.
The returned object needs to have the method each() that goes through each selected HTML element.
Note that the each() method has a parameter of function which will be invoked in each().
n numbers, adds them and returns the result using a callback function.
this keyword and functions, especially with callback functionsthis.
<script>
function printType(msg, x) {
if (x == window) alert(msg + ": " + 'window');
else if (x == document) alert(msg + ": " + 'document');
else if (x instanceof HTMLElement) alert(msg + ": " + 'HTMLElement ' + x.id);
else alert(msg + ": " + 'something else');
}
function foo() {
printType("foo-this", this); // what is this?
}
function goo(obj, callback) {
printType("goo-this", this); // what is this?
foo();
printType("goo-obj", obj); // what is obj?
callback(); // check 'this' in callback() carefully.
// a very important trick; There is another way and we will see it later.
obj.__TRUjQ__callback = callback;
obj.__TRUjQ__callback(); // check 'this' in callback() carefully.
}
$('#tr1-button').click(function() {
printType("button-click-this", this); // what is this?
let this_button = this;
goo(this, function() {
printType("goo-callback-this", this); // what is this?
printType("goo-callback-this_button", this_button);
});
});
</script>
<p id='tr1-p'>Interesting!</p>
<button id='tr1-button'>Click me!</button>
event listener for the click over the button: // It is defined on the button HTMLElement object.
alert() with this;
goo(this, callback): // goo is defined in ???.
alert() with this;
foo(): // foo is defined in ???.
alert() with this;
alert() with the passed argument;
callback(): // Where is it defined?
alert() with this;
alert() with this_button;
obj.__TRUjQ__callback():
alert() with this;
alert() with this_button;
var and let work differently. What will be printed?
<script>
function foo(lists) {
let fts = [];
for (let i = 0; i < lists.length; i++) {
var p = lists[i]; // what if 'let' is used instead of 'var'?
fts[i] = function() {
alert(p); // p cannot be destroyed at the end of each for-iteration.
// what if 'lists[i]' is used instead of 'p'?
};
}
return fts; // array of functions
}
function goo() {
let lists = [1, 2, 3];
let fts = foo(lists);
for (let i = 0; i < fts.length; i++)
fts[i](); // What will be printed? 1, 2, and 3?
}
$('#tr2-button').click(function() { goo(); });
</script>
<button id='tr2-button'>Click me to test the above code!</button>
let p = lists[i];.
var p, but 1, 2, and 3 with let p.
When this function is called, p is evaluated and it will be 3, 3, and 3.